package com.ruibang.glass.produce.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.Constants;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceCreate;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceStatus;
import com.ruibang.glass.common.domain.camunda.BpmTaskApproveReq;
import com.ruibang.glass.common.domain.material.*;
import com.ruibang.glass.common.utils.AssertUtil;
import com.ruibang.glass.produce.constant.ProduceErrorCode;
import com.ruibang.glass.produce.domain.req.RawMaterialReceiveReq;
import com.ruibang.glass.produce.entity.MaterialItemInfo;
import com.ruibang.glass.produce.entity.RawMaterialReceive;
import com.ruibang.glass.produce.feign.CamundaApi;
import com.ruibang.glass.produce.feign.MaterialApi;
import com.ruibang.glass.produce.mapper.RawMaterialReceiveMapper;
import com.ruibang.glass.produce.service.MaterialItemInfoService;
import com.ruibang.glass.produce.service.RawMaterialReceiveService;
//import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import org.apache.commons.collections4.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @Author: songJinKang
 * @CreateTime: 2024-03-18  19:40
 * @Description: TODO
 * @Version: 1.0
 */

@Slf4j
@Service
public class RawMaterialReceiveServiceImpl extends ServiceImpl<RawMaterialReceiveMapper, RawMaterialReceive> implements RawMaterialReceiveService {

    @Autowired
    private CamundaApi camundaApi;

    @Autowired
    private MaterialItemInfoService materialItemInfoService;

    @Autowired
    private CommonService commonService;

//    @Autowired
//    private RedisSingleService redisService;

    @Autowired
    private RedisSingleService redisService;

    @Autowired
    private MaterialApi materialApi;

//    @PostConstruct
//    public void initData() {
//        List<RawMaterialReceive> list = this.list();
//        for (RawMaterialReceive rawMaterialReceive : list) {
//            String planPickerId = rawMaterialReceive.getPlanPickerId();
//            if (StringUtils.isNotBlank(planPickerId)){
//                Object planObj = redisService.hget(RedisKey.USER_GROUP_TYPE, planPickerId);
//                if (planObj!=null){
//                    rawMaterialReceive.setPlanPicker(planObj.toString());
//                }
//            }
//        }
//        this.updateBatchById(list);
//    }


    @Override
    public void deleteById(String id) {
        lambdaUpdate().eq(RawMaterialReceive::getMaterialReceiveId, id).set(RawMaterialReceive::getIsDelete, Constants.ONE_STR).update();
    }


    @Override
    public RawMaterialReceive getDetails(String id) {
        RawMaterialReceive rawMaterialReceive = this.getById(id);
        if (rawMaterialReceive != null) {
            //获取申请物品信息
            List<MaterialItemInfo> materialItemInfos = materialItemInfoService.getByMaterialReceiveId(id);
            if (CollectionUtils.isNotEmpty(materialItemInfos)) {
                rawMaterialReceive.setMaterialItemInfo(materialItemInfos);
            }
        }
        return rawMaterialReceive;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBody insert(RawMaterialReceive rawMaterialReceive) {
        //申请物品
        List<MaterialItemInfo> materialItemInfo = rawMaterialReceive.getMaterialItemInfo();
        if (CollectionUtils.isEmpty(materialItemInfo)) {
            return ResultBody.fail(ProduceErrorCode.APPLY_ITEM_IS_NULL.getCode(), ProduceErrorCode.APPLY_ITEM_IS_NULL.getMsg());
        }

        //判断是否有相同物品
        List<String> sameItem = materialItemInfo.stream()
                .map(e -> e.getItemId().concat(e.getBatchNumber()).concat(e.getCode()).concat(e.getWarehouseLocationId()))
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream().filter(e -> e.getValue() > 1)
                .map(Map.Entry::getKey).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(sameItem)) {
            return ResultBody.fail(ProduceErrorCode.SAME_MATERIAL_APPLY_FAIL.getCode(), ProduceErrorCode.SAME_MATERIAL_APPLY_FAIL.getMsg());
        }

        //申请数量判断
        long count = materialItemInfo.stream().filter(e -> e.getCount().compareTo(BigDecimal.valueOf(0)) <= Constants.ZERO_INT).count();
        if (count > 0) {
            return ResultBody.fail(ProduceErrorCode.APPLY_ITEM_IS_ZERO.getCode(), ProduceErrorCode.APPLY_ITEM_IS_ZERO.getMsg());
        }

        //库存数量判断
        ResultBody<List<MaterialALLInventoryManagementDTO>> resultBody = materialApi.getYclMaterialList();
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            List<MaterialALLInventoryManagementDTO> data = resultBody.getData();
            Map<String, MaterialALLInventoryManagementDTO> materialMap = data.stream().collect(Collectors.toMap(MaterialALLInventoryManagementDTO::getId, e -> e));
            for (MaterialItemInfo itemInfo : materialItemInfo) {
                MaterialALLInventoryManagementDTO material = materialMap.get(itemInfo.getInventoryId());
                AssertUtil.isFalse(material == null, itemInfo.getItemName().concat("库存信息为空！"));
                AssertUtil.isFalse(material.getAvailableQuantity() == null, itemInfo.getItemName().concat("库存可用数量为空！"));
                //判断可用数量
                AssertUtil.isFalse(itemInfo.getCount().compareTo(material.getAvailableQuantity()) > 0, "领用数量不可大于库存数量，库存可用数：".concat(material.getAvailableQuantity().toString()));
            }
        } else {
            throw new ServiceException(ProduceErrorCode.NOT_FOUND_YCL_MATERIAL_INFO.getCode(), ProduceErrorCode.NOT_FOUND_YCL_MATERIAL_INFO.getMsg());
        }


        //获取物品类型名称
        ResultBody<List<WareHouseInfoDTO>> result = materialApi.getLocationItemList();
        if (result != null && CollectionUtils.isNotEmpty(result.getData())) {
            List<WareHouseInfoDTO> wareHouseInfo = result.getData();
            Map<String, String> wareHouseInfoMap = wareHouseInfo.stream().collect(Collectors.toMap(WareHouseInfoDTO::getWareHouseCode, WareHouseInfoDTO::getWareHouseName));
            rawMaterialReceive.setItemTypeName(wareHouseInfoMap.get(rawMaterialReceive.getItemType()));
        }


        //保存申请单据
        rawMaterialReceive.setIsDelete(Constants.ZERO_STR);
//        rawMaterialReceive.setOrderNo(generateOrderNo());
        String planPickerId = rawMaterialReceive.getPlanPickerId();
        Object userName = redisService.hget(RedisKey.USER_GROUP_TYPE, planPickerId);
        if (userName != null) {
            rawMaterialReceive.setPlanPicker(userName.toString());
        }
        this.save(rawMaterialReceive);


        //保存申请物品
        for (MaterialItemInfo itemInfo : materialItemInfo) {
            itemInfo.setMaterialReceiveId(rawMaterialReceive.getMaterialReceiveId());
        }
        materialItemInfoService.saveBatch(materialItemInfo);

        return ResultBody.success();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBody edit(RawMaterialReceive rawMaterialReceive) {
        //申请物品
        List<MaterialItemInfo> materialItemInfo = rawMaterialReceive.getMaterialItemInfo();
        List<MaterialItemInfo> oldItemInfo = materialItemInfoService.getByMaterialReceiveId(rawMaterialReceive.getMaterialReceiveId());
        Map<String, MaterialItemInfo> oldItemMap = oldItemInfo.stream().collect(Collectors.toMap(MaterialItemInfo::getInventoryId, e -> e));
        if (CollectionUtils.isEmpty(materialItemInfo)) {
            return ResultBody.fail(ProduceErrorCode.APPLY_ITEM_IS_NULL.getCode(), ProduceErrorCode.APPLY_ITEM_IS_NULL.getMsg());
        }

        //判断是否有相同物品
        List<String> sameItem = materialItemInfo.stream()
                .map(MaterialItemInfo::getInventoryId)
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream().filter(e -> e.getValue() > 1)
                .map(Map.Entry::getKey).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(sameItem)) {
            return ResultBody.fail(ProduceErrorCode.SAME_MATERIAL_APPLY_FAIL.getCode(), ProduceErrorCode.SAME_MATERIAL_APPLY_FAIL.getMsg());
        }

        //申请数量判断
        long count = materialItemInfo.stream().filter(e -> e.getCount().compareTo(BigDecimal.valueOf(0)) <= Constants.ZERO_INT).count();
        if (count > 0) {
            return ResultBody.fail(ProduceErrorCode.APPLY_ITEM_IS_ZERO.getCode(), ProduceErrorCode.APPLY_ITEM_IS_ZERO.getMsg());
        }

        //库存数量判断
        ResultBody<List<MaterialALLInventoryManagementDTO>> resultBody = materialApi.getYclMaterialList();
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            List<MaterialALLInventoryManagementDTO> data = resultBody.getData();
            Map<String, MaterialALLInventoryManagementDTO> materialMap = data.stream().collect(Collectors.toMap(MaterialALLInventoryManagementDTO::getId, e -> e));
            for (MaterialItemInfo itemInfo : materialItemInfo) {
                MaterialItemInfo oldItem = oldItemMap.get(itemInfo.getInventoryId());
                //如果与旧的物品 领取数量相同就不做判断
                if (oldItem != null && oldItem.getCount().compareTo(itemInfo.getCount()) != 0) {
                    MaterialALLInventoryManagementDTO material = materialMap.get(itemInfo.getInventoryId());
                    AssertUtil.isFalse(material == null, itemInfo.getItemName().concat("库存信息为空！"));
                    AssertUtil.isFalse(material.getAvailableQuantity() == null, itemInfo.getItemName().concat("库存可用数量为空！"));
                    //判断可用数量
                    AssertUtil.isFalse(itemInfo.getCount().compareTo(material.getAvailableQuantity().add(oldItem.getCount())) > 0, "领用数量不可大于库存数量，库存可用数：".concat(material.getAvailableQuantity().toString()));
//                    AssertUtil.isFalse(itemInfo.getCount().compareTo(material.getAvailableQuantity()) > 0, "领用数量不可大于库存数量，库存可用数：".concat(material.getAvailableQuantity().toString()));
                }
            }
        }

        //修改
        this.updateById(rawMaterialReceive);

        //修改库存
        RawMaterialReceive oldRawMaterialReceive = this.getDetails(rawMaterialReceive.getMaterialReceiveId());
        if (oldRawMaterialReceive != null) {
            String approveStatus = oldRawMaterialReceive.getApproveStatus();
            if (StringUtils.isNotBlank(approveStatus) && !approveStatus.equals(Constants.ZERO_STR) && !approveStatus.equals(Constants.FOUR_STR)) {
                //解冻库存
                List<MaterialItemInfo> oldMaterialItemInfo = oldRawMaterialReceive.getMaterialItemInfo();
                if (CollectionUtils.isNotEmpty(oldMaterialItemInfo)) {
                    List<MaterialALLInventoryManagementReq> oldData = new ArrayList<>();
                    for (MaterialItemInfo itemInfo : oldMaterialItemInfo) {
                        MaterialALLInventoryManagementReq materialAllInventoryManagementReq = new MaterialALLInventoryManagementReq();
                        materialAllInventoryManagementReq.setItemCode(itemInfo.getItemCode());
                        materialAllInventoryManagementReq.setBarcodeNumber(itemInfo.getCode());
                        materialAllInventoryManagementReq.setBatchNumber(itemInfo.getBatchNumber());
                        materialAllInventoryManagementReq.setFrozenQuantity(itemInfo.getCount());
                        materialAllInventoryManagementReq.setStorageLocationId(itemInfo.getWarehouseLocationId());
                        oldData.add(materialAllInventoryManagementReq);
                    }
                    materialApi.removeFrozenQuantity(oldData);
                }
                //封锁库存
                List<MaterialALLInventoryManagementReq> newData = new ArrayList<>();
                for (MaterialItemInfo itemInfo : materialItemInfo) {
                    MaterialALLInventoryManagementReq materialAllInventoryManagementReq = new MaterialALLInventoryManagementReq();
                    materialAllInventoryManagementReq.setItemCode(itemInfo.getItemCode());
                    materialAllInventoryManagementReq.setBarcodeNumber(itemInfo.getCode());
                    materialAllInventoryManagementReq.setBatchNumber(itemInfo.getBatchNumber());
                    materialAllInventoryManagementReq.setFrozenQuantity(itemInfo.getCount());
                    materialAllInventoryManagementReq.setStorageLocationId(itemInfo.getWarehouseLocationId());
                    newData.add(materialAllInventoryManagementReq);
                }
                materialApi.updateFrozenQuantity(newData);
            }
        }

        //修改物品
        String materialReceiveId = rawMaterialReceive.getMaterialReceiveId();
        materialItemInfoService.deleteByMaterialReceiveId(materialReceiveId);
        if (CollectionUtils.isNotEmpty(rawMaterialReceive.getMaterialItemInfo())) {
            rawMaterialReceive.getMaterialItemInfo().forEach(e -> {
                e.setId(null);
                e.setMaterialReceiveId(materialReceiveId);
            });
            materialItemInfoService.saveBatch(rawMaterialReceive.getMaterialItemInfo());
        }
        return ResultBody.success();
    }

    @Override
    public String getOrderNo() {
        LocalDateTime now = LocalDateTime.now();
        Serializable serializable = redisService.get(Constants.RAW_MATERIAL_RECEIVE_SERIAL_NUMBER);
        String serialNumber;
        if (serializable == null) {
            serialNumber = String.format("%04d", Constants.ONE_INT);
        } else {
            int serialNum = Integer.parseInt(serializable.toString());
            if (serialNum > Constants.ORDER_NO_SERIAL_NUMBER_UP) {
                serialNum = Constants.ONE_INT;
            }
            serialNumber = String.format("%04d", serialNum);
        }
        return "MP".concat(String.valueOf(now.getYear()))
                .concat(String.valueOf(String.format("%02d", now.getMonthValue())))
                .concat(String.valueOf(String.format("%02d", now.getDayOfMonth()))).concat(serialNumber);
    }

    @Override
    public void processNotice(String businessId) {
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Collections.singletonList(businessId));
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            //流程实例信息
            BpmProcessInstanceStatus process = resultBody.getData().get(0);

            //业务数据
            RawMaterialReceive rawMaterialReceive = this.getDetails(businessId);

            if (rawMaterialReceive != null && CollectionUtils.isNotEmpty(rawMaterialReceive.getMaterialItemInfo())) {
                //如果拒绝冻结库存全部回退
                if (Constants.FOUR_STR.equals(rawMaterialReceive.getApproveStatus())) {
                    List<MaterialALLInventoryManagementReq> dataList = new ArrayList<>();
                    for (MaterialItemInfo materialItemInfo : rawMaterialReceive.getMaterialItemInfo()) {
                        MaterialALLInventoryManagementReq materialAllInventoryManagementReq = new MaterialALLInventoryManagementReq();
                        materialAllInventoryManagementReq.setItemCode(materialItemInfo.getItemCode());
                        materialAllInventoryManagementReq.setBarcodeNumber(materialItemInfo.getCode());
                        materialAllInventoryManagementReq.setBatchNumber(materialItemInfo.getBatchNumber());
                        materialAllInventoryManagementReq.setFrozenQuantity(materialItemInfo.getCount());
                        materialAllInventoryManagementReq.setStorageLocationId(materialItemInfo.getWarehouseLocationId());
                        dataList.add(materialAllInventoryManagementReq);
                    }
                    materialApi.removeFrozenQuantity(dataList);
                }


                //出库申请
                if (process.getNodeKey().equals(Constants.FINISH_NODE_KEY)) {
                    //调用发起出库申请
                    MaterialALLOutboundManagement materialALLOutboundManagement = new MaterialALLOutboundManagement();
                    materialALLOutboundManagement.setWarehouseName(rawMaterialReceive.getWarehouseName());
                    materialALLOutboundManagement.setWarehouseId(rawMaterialReceive.getWarehouseId());
                    materialALLOutboundManagement.setUseReason(rawMaterialReceive.getOutboundPurpose());
                    materialALLOutboundManagement.setUsePersonId(rawMaterialReceive.getPlanPickerId());
                    materialALLOutboundManagement.setUsePerson(rawMaterialReceive.getPlanPicker());
                    materialALLOutboundManagement.setPlanMaterialDate(rawMaterialReceive.getPlanTime());
                    materialALLOutboundManagement.setType(rawMaterialReceive.getOutboundType());
                    materialALLOutboundManagement.setOutNumber(rawMaterialReceive.getOrderNo());
                    materialALLOutboundManagement.setItemType(rawMaterialReceive.getItemType());
                    //设置物品信息
                    List<MaterialAllOutboundItem> itemList = new ArrayList<>();
                    for (MaterialItemInfo materialItemInfo : rawMaterialReceive.getMaterialItemInfo()) {
                        MaterialAllOutboundItem materialAllOutboundItem = new MaterialAllOutboundItem();
                        materialAllOutboundItem.setItemName(materialItemInfo.getItemName());
                        materialAllOutboundItem.setItemId(materialItemInfo.getItemId());
                        materialAllOutboundItem.setBarcodeNumber(materialItemInfo.getCode());
                        materialAllOutboundItem.setBatchNumber(materialItemInfo.getBatchNumber());
                        materialAllOutboundItem.setUnit(materialItemInfo.getUnit());
                        materialAllOutboundItem.setQuantity(materialItemInfo.getCount());
                        materialAllOutboundItem.setSpecification(materialItemInfo.getSpecification());
                        materialAllOutboundItem.setSerialNumber(materialItemInfo.getSerialNumber());
                        materialAllOutboundItem.setContentPercentage(materialItemInfo.getContent());
                        materialAllOutboundItem.setSupplierName(materialItemInfo.getSupplierName());
                        materialAllOutboundItem.setSupplierId(materialItemInfo.getSupplierId());
                        materialAllOutboundItem.setStorageLocationId(materialItemInfo.getWarehouseLocationId());
                        materialAllOutboundItem.setStorageLocationName(materialItemInfo.getWarehouseLocationName());
                        itemList.add(materialAllOutboundItem);
                    }
                    materialALLOutboundManagement.setMaterialAllOutboundItemList(itemList);
                    //发起申请
                    log.error(JSON.toJSONString(materialALLOutboundManagement));
                    materialApi.addMaterialYClOutboundManagement(materialALLOutboundManagement);
                }
            }


        }
    }


    @Override
    public IPage<RawMaterialReceive> pageQuery(RawMaterialReceiveReq rawMaterialReceiveReq) {
        QueryWrapper<RawMaterialReceive> qw = new QueryWrapper<>();
        qw.lambda().eq(RawMaterialReceive::getIsDelete, Constants.ZERO_STR);
        qw.lambda().like(StringUtils.isNotBlank(rawMaterialReceiveReq.getOrderNo()), RawMaterialReceive::getOrderNo, rawMaterialReceiveReq.getOrderNo());
        qw.lambda().eq(StringUtils.isNotBlank(rawMaterialReceiveReq.getPlanPickerId()), RawMaterialReceive::getPlanPickerId, rawMaterialReceiveReq.getPlanPickerId());
        qw.lambda().eq(StringUtils.isNotBlank(rawMaterialReceiveReq.getOutboundType()), RawMaterialReceive::getOutboundType, rawMaterialReceiveReq.getOutboundType());
        if (rawMaterialReceiveReq.getStartTime() != null && rawMaterialReceiveReq.getEndTime() != null) {
            qw.lambda().ge(RawMaterialReceive::getPlanTime, rawMaterialReceiveReq.getStartTime());
            qw.lambda().le(RawMaterialReceive::getPlanTime, rawMaterialReceiveReq.getEndTime());
        }
        qw.lambda().orderByDesc(RawMaterialReceive::getCreateTime);
        Page<RawMaterialReceive> page = this.page(new Page<>(rawMaterialReceiveReq.getPageNo(), rawMaterialReceiveReq.getPageSize()), qw.lambda());
        if (page != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            List<RawMaterialReceive> rawMaterialReceiveList = page.getRecords();
            List<String> ids = rawMaterialReceiveList.stream().map(RawMaterialReceive::getMaterialReceiveId).collect(Collectors.toList());
            //获取申请物品信息
            List<MaterialItemInfo> materialItemInfos = materialItemInfoService.getByMaterialReceiveLIds(ids);
            if (CollectionUtils.isNotEmpty(materialItemInfos)) {
                Map<String, List<MaterialItemInfo>> materialItemInfoMap = materialItemInfos.stream().collect(Collectors.groupingBy(MaterialItemInfo::getMaterialReceiveId));
                for (RawMaterialReceive rawMaterialReceive : rawMaterialReceiveList) {
                    rawMaterialReceive.setMaterialItemInfo(materialItemInfoMap.get(rawMaterialReceive.getMaterialReceiveId()));
                }
            }

            //流程信息
            ResultBody<List<BpmProcessInstanceStatus>> bpmResultBody = camundaApi.queryProcessInstanceStatus(ids);
            if (bpmResultBody != null && CollectionUtils.isNotEmpty(bpmResultBody.getData())) {
                List<BpmProcessInstanceStatus> bpmProcessInstanceStatusList = bpmResultBody.getData();
                Map<String, BpmProcessInstanceStatus> bpmProcessInstanceStatusMap = bpmProcessInstanceStatusList.stream().collect(Collectors.toMap(BpmProcessInstanceStatus::getBusinessKey, e -> e, (oldEl, newEl) -> newEl));
                for (RawMaterialReceive rawMaterialReceive : rawMaterialReceiveList) {
                    BpmProcessInstanceStatus bpmProcessInstanceStatus = bpmProcessInstanceStatusMap.get(rawMaterialReceive.getMaterialReceiveId());
                    if (bpmProcessInstanceStatus != null) {
                        String userId = bpmProcessInstanceStatus.getUserId();
                        if (StringUtils.isNotBlank(userId)) {
                            Object userNameObj = redisService.hget(RedisKey.USER_GROUP_TYPE, userId);
                            if (userNameObj != null) {
                                rawMaterialReceive.setCurrentAuditBy(userNameObj.toString());
                            }
                            rawMaterialReceive.setApproveUserId(userId);
                        }
                        rawMaterialReceive.setProcessInstanceId(bpmProcessInstanceStatus.getProcessInstanceId());
                        rawMaterialReceive.setNodeKey(bpmProcessInstanceStatus.getNodeKey());
                        rawMaterialReceive.setNodeName(bpmProcessInstanceStatus.getNodeName());
                    }
                }
            }
        }
        return page;
    }


    @Override
    public ResultBody startProcess(BpmProcessInstanceCreate bpmProcessInstanceCreate) {
        RawMaterialReceive rawMaterialReceive = this.getById(bpmProcessInstanceCreate.getBusinessKey());
        List<MaterialItemInfo> materialItemInfos = materialItemInfoService.getByMaterialReceiveId(bpmProcessInstanceCreate.getBusinessKey());

        //申请物品为空不可发起流程
        if (CollectionUtils.isEmpty(materialItemInfos)) {
            throw new ServiceException(ProduceErrorCode.APPLY_ITEM_IS_NULL_NO_START_PROCESS.getCode(), ProduceErrorCode.APPLY_ITEM_IS_NULL_NO_START_PROCESS.getMsg());
        }

        if (rawMaterialReceive != null && CollectionUtils.isNotEmpty(materialItemInfos)) {
            //库存数量判断
            ResultBody<List<MaterialALLInventoryManagementDTO>> resultBody = materialApi.getYclMaterialList();
            if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
                List<MaterialALLInventoryManagementDTO> data = resultBody.getData();
                Map<String, MaterialALLInventoryManagementDTO> materialMap = data.stream().collect(Collectors.toMap(MaterialALLInventoryManagementDTO::getId, e -> e));
                for (MaterialItemInfo itemInfo : materialItemInfos) {
                    //如果与旧的物品 领取数量相同就不做判断
                    MaterialALLInventoryManagementDTO material = materialMap.get(itemInfo.getInventoryId());
                    AssertUtil.isFalse(material == null, itemInfo.getItemName().concat("库存信息为空！"));
                    AssertUtil.isFalse(material.getAvailableQuantity() == null, itemInfo.getItemName().concat("库存可用数量为空！"));
                    //判断可用数量
                    AssertUtil.isFalse(itemInfo.getCount().compareTo(material.getAvailableQuantity()) > 0, "领用数量不可大于库存数量，库存可用数：".concat(material.getAvailableQuantity().toString()));
                }
            } else {
                throw new ServiceException(ProduceErrorCode.NOT_FOUND_YCL_MATERIAL_INFO.getCode(), ProduceErrorCode.NOT_FOUND_YCL_MATERIAL_INFO.getMsg());
            }

            //发起流程
            Map<String, Object> variables = new HashMap<>(16);
            variables.put(Constants.PROCESS_INSTANCE_STARTER_USER_ID, rawMaterialReceive.getPlanPickerId());
            variables.put(Constants.PROCESS_INSTANCE_BUSINESS_KEY, rawMaterialReceive.getMaterialReceiveId());
            variables.put(Constants.PROCESS_INSTANCE_MENU_ID, bpmProcessInstanceCreate.getMenuId());
            bpmProcessInstanceCreate.setVariables(variables);
            bpmProcessInstanceCreate.setBusinessKey(rawMaterialReceive.getMaterialReceiveId());
            bpmProcessInstanceCreate.setMenuId(bpmProcessInstanceCreate.getMenuId());
            String processId = commonService.startProcess(bpmProcessInstanceCreate);

            //过第一流程节点
            if (StringUtils.isNotBlank(processId)) {
                BpmTaskApproveReq bpmTaskApproveReq = new BpmTaskApproveReq();
                bpmTaskApproveReq.setId(processId);
                bpmTaskApproveReq.setUserId(rawMaterialReceive.getPlanPickerId());
                camundaApi.approve(bpmTaskApproveReq);
            }

            //库存冻结
            List<MaterialALLInventoryManagementReq> materialALLInventoryManagementReqList = new ArrayList<>();
            for (MaterialItemInfo materialItemInfo : materialItemInfos) {
                MaterialALLInventoryManagementReq materialALLInventoryManagementReq = new MaterialALLInventoryManagementReq();
                materialALLInventoryManagementReq.setItemCode(materialItemInfo.getItemCode());
                materialALLInventoryManagementReq.setBarcodeNumber(materialItemInfo.getCode());
                materialALLInventoryManagementReq.setBatchNumber(materialItemInfo.getBatchNumber());
                materialALLInventoryManagementReq.setFrozenQuantity(materialItemInfo.getCount());
                materialALLInventoryManagementReq.setStorageLocationId(materialItemInfo.getWarehouseLocationId());
                materialALLInventoryManagementReqList.add(materialALLInventoryManagementReq);
            }
            materialApi.updateFrozenQuantity(materialALLInventoryManagementReqList);


        } else {
            throw new ServiceException(ProduceErrorCode.RAW_MATERIAL_RECEIVE_START_PROCESS_FAIL.getCode(), ProduceErrorCode.RAW_MATERIAL_RECEIVE_START_PROCESS_FAIL.getMsg());
        }
        return ResultBody.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteInfo(String id) {
        if (StringUtils.isNotBlank(id)) {
            RawMaterialReceive rawMaterialReceive = getById(id);
            if (rawMaterialReceive != null) {
                if (!Constants.ZERO_STR.equals(rawMaterialReceive.getApproveStatus())) {
                    throw new ServiceException(ProduceErrorCode.NEW_STATUS_CANNOT_BE_DELETE.getCode(), ProduceErrorCode.NEW_STATUS_CANNOT_BE_DELETE.getMsg());
                }
                this.deleteById(id);
                //物品记录
                materialItemInfoService.deleteByMaterialReceiveId(id);
            }
        }
    }


    /**
     * @Description: 获取申请单号
     * @version v1.0
     * @author songJinKang
     * @date 2024-03-21 10:49
     */
    public String generateOrderNo() {
        LocalDateTime now = LocalDateTime.now();
        Serializable serializable = redisService.get(Constants.RAW_MATERIAL_RECEIVE_SERIAL_NUMBER);
        String serialNumber;
        if (serializable == null) {
            serialNumber = String.format("%04d", Constants.ONE_INT);
        } else {
            int serialNum = Integer.parseInt(serializable.toString());
            if (serialNum > Constants.ORDER_NO_SERIAL_NUMBER_UP) {
                serialNum = Constants.ONE_INT;
                redisService.set(Constants.RAW_MATERIAL_RECEIVE_SERIAL_NUMBER, Constants.ONE_INT);
            }
            serialNumber = String.format("%04d", serialNum);
        }
        String orderStr = "MP".concat(String.valueOf(now.getYear()))
                .concat(String.valueOf(String.format("%02d", now.getMonthValue())))
                .concat(String.valueOf(String.format("%02d", now.getDayOfMonth()))).concat(serialNumber);
        redisService.incr(Constants.RAW_MATERIAL_RECEIVE_SERIAL_NUMBER, Constants.ONE_INT);
        return orderStr;
    }
}
